#ifndef __LS_EXTENSION_H__
#define __LS_EXTENSION_H__

#include "../log_system/sink.hpp"

namespace extensionLS
{
    enum class TimeInterval
    {
        SECOND_INTERVAL,
        MINUTE_INTERVAL,
        HOUR_INTERVAL,
        DAY_INTERVAL,
        WEEK_INTERVAL
    };

    class RollingByTimeSink : public log_system::LogSink
    {
    public:
        RollingByTimeSink(const std::string& baseName, TimeInterval interval_type)
            :_baseName(baseName)
        {
            switch (interval_type)
            {
            case TimeInterval::SECOND_INTERVAL: _interval = 1;  break;
            case TimeInterval::MINUTE_INTERVAL: _interval = 60; break;
            case TimeInterval::HOUR_INTERVAL:   _interval = 60 * 60;    break;
            case TimeInterval::DAY_INTERVAL:    _interval = 60 * 60 * 24;   break;
            case TimeInterval::WEEK_INTERVAL:   _interval = 60 * 60 * 24 * 7;   break;
            }

            log_system::util::File::createDirectory(log_system::util::File::parentPath(_baseName));
            createNewFile();
        }

        void log(const char* data, size_t len) override
        {
            if(_curPeriod != log_system::util::Date::now() / _interval)  createNewFile();
            _ofs.write(data, len);
            assert(_ofs.good());
        }

    private:
        void createNewFile()
        {
            if(_ofs.is_open())  _ofs.close();

            std::string fileName = getFileName();
            _ofs.open(fileName, std::ios::binary | std::ios::app);
            assert(_ofs.is_open());

            _curPeriod = log_system::util::Date::now() / _interval;
        }

        std::string getFileName()
        {
            std::stringstream ss;

            time_t t = log_system::util::Date::now();
            struct tm* ptm = localtime(&t);
            
            char buffer[32] = { 0 };
            strftime(buffer, sizeof(buffer), "%Y-%m-%d_%H-%M-%S", ptm);

            ss << _baseName;
            ss << buffer;
            ss << ".log";

            return ss.str();
        }
    private:
        std::string _baseName;
        std::ofstream _ofs;
        size_t _interval;
        size_t _curPeriod;
    };
}



#endif